# 39. os模块 - 系统交互模块

# os系统模块

os模块是一个直接跟操作系统交互的模块

常用的模块方法,分成二个部分,os部分,os.path部分

# os部分

os部分模块方法分为几个部分

# 跟工作目录相关

# 获取当前目录 - os.getcwd

实际是返回当前在那执行的路径

import os
print(os.getcwd())

执行结果:
D:\python\PyCharm资源\one\模块

也有认为是返回当前文件的目录路径,其实不是的,在pycharm中是不太明显的,可以去命令行或centos中实验

可以看下一个方法

# 改变当前工作目录 - os.chdir

改变你当前执行的目录,相当linux下的cd命令

import os
print(os.chdir("c:"))
print(os.getcwd())

执行结果:
None
C:\

# 返回当前目录 - os.curdir

返回当前目录,一直都是返回 . 当然 . 也是代表当前目录

import os
print(os.curdir)

执行结果:
.

# 返回当前目录的父目录 - os.pardir

返回当前目录的父目录,一直都是返回 .. 当然 .. 也是代表当前目录的上级目录

import os
print(os.pardir)

执行结果:
..

# 跟文件与目录相关

# 生成单层目录 - os.mkdir

生成单层目录,就是生成一个目录,类似linux下的mkdir

import os
os.mkdir("python1")

## 在当前目录下生成python1目录

# 生成多层目录 - os.makedire

生成多层目录,就是递归生成多个目录,类似linux下的mkdir -p

exist_ok 选项:

  1. exist_ok = Fales:默认选项,如果要生成的目录存在,则程度报错
  2. exist_ok = True:定义选项,如果要生成的目录存在,则不生成
import os
os.mkdir("python1/python2",exist_ok = True)

## 在当前目录下生成python1目录和在python1目录下生成python2目录

# 删除单层目录 - os.rmdir

删除单层目录,如果目录中不为空则删除不了

import os
os.rmdir("python1")

## 删除当前目录下的Python1目录

# 删除多层目录 - os.removedire

删除多层目录,先删除最后的目录,如果为空则删除,在删除上一级目录,如果为空则也删除,依此类推

import os
os.rmdir("python1/python2")

## 删除Python1目录下的Python2目录跟当前目录下的python2目录

# 重命名文件或目录 - os.rename

格式:os.rename("文件名或目录名","新文件名或新目录名")

import os
os.rename("python1","python2")

## 在当前目录中把python1目录更改为python2目录

# 删除文件 - os.remove

格式:os.remove("文件名")

import os
os.remove("python1")

## 在当前目录下把python1文件删除

# 列出指定目录下的所有 - os.listdir

列表指定目录下的所有文件跟目录,包含隐藏文件,并以列表类型方式打印

import os
print(os.listdir("a"))

执行结果:
['aaa', 'b', 'c', 'sgmso', '__init__.py']

# 查看文件或目录的详细信息

可以获得文件或目录的详细信息

stat结构名 函义
st_mode inode 保护模式
st_ino inode 节点号
st_dev inode 驻留的设备
st_nlink inode 的链接数
st_uid 所有者的用户ID
st_gid 所有者的组ID
st_size 普通文件以字节为单位的大小;包含等待某些特殊文件的数据
st_atime 上次访问的时间
st_mtime 最后一次修改的时间
st_ctime 由操作系统报告的"ctime"。在某些系统上(如Unix)是最新的元数据更改的时间,在其它系统上(如Windows)是创建时间(详细信息参见平台的文档)
import os
print(os.stat("a"))

执行结果:
os.stat_result(st_mode=16895, st_ino=2533274790537096, st_dev=271629774, st_nlink=1, st_uid=0, st_gid=0, st_size=0, st_atime=1569146582, st_mtime=1568080930, st_ctime=1568001494)

# 区分操作系统差异

# 操作系统特定的路径分隔符 - os.sep

输出操作系统特定的路径分隔符,win下为"\\" , linux下为"/"

import os
print(os.sep)
print([os.sep])

执行结果:
\
['\\']

## 为什么加上列表才是二个 \\ 呢,因为 \ 对于系统是有特殊函义的,所以系统要显示无意义的 \ 就要在加个 \ 去意 ,所以在列表显示就能现圆形

# 当前平台使用的行终止符 - os.linesep

输出当前平台使用的行终止符,win下为"\t \n" ,linux下为"\n"

import os
print(os.linesep)
print([os.linesep])

执行结果:


['\r\n']

## 为什么加列表能输出 \r\n,而直接os.linesep,就不能显示,因为在win中\r\n 代表的就是换行,所以python输出执行出结果就会被系统默认的执行\r\n的功能,而列表就能让\r\n现出原形 

# 用于分割文件路径的字符串-os.pathsep

输出当前操作系统用于分割文件路径的字符串,win下为" ; " ,linux下为" : "

import os
print(os.pathsep)

执行结果:
;

## 这里又为什么不加列表了,因为加列表跟没列表的结果是一样的,就不加了

# 输出当前使用平台 - os.name

输出显示当前使用的平台,用字符串显示,win下为" nt " ,linux下为" posix "

数据类型:字符串

import os
print(os.name)

执行结果:
nt

## 当前的操作系统是win,所以显示nt

# 跟操作系统交互

# 使用操作系统命令 - 直接显示 - os.system

import os
os.system("dir")
so = os.system("dir")

## 不写执行结果,因为执行结果太长
## 可以发现,没打印os.system,但是在执行的时候,os.system会自己的输出在当前屏幕中

# 使用操作系统命令 - 不直接显示 - os.popen

import os
so = os.popen("dir")
print(os.popen("dir"))
print(os.popen("dir").read())
print(so)
print(so.read())

## 不写执行结果,因为执行结果太长
## 可以发现,os.popen如果不加read()的话,打印出来的就只能内存地址,只有加了read(),才能打印真正的内容

# 获取系统环境变量 - os.environ

import os
print(os.environ)

## 不写执行结果,因为执行结果太长
## 打印当前系统的环境变量

# 其他用法

# 获取指定大小的随机数 - bytes类型 - os.urandom

获取指定大小的随机数,但是这随机数是bytes类型的

import os
r = os.urandom(16)
print(r)

执行结果:
b'V\x98f\xc1\xc6\x8e\xc3\xc2\x81\x8cv\xa86\x94.P'

# 获取当前执行的进程PID - os.getpid()

获取的是当前执行的进程的PID号

import os
print(os.getpid())

执行结果:
6862

# 获取当前执行进程父进程PID - os.getppid()

获取的是当前执行的进程的父进程的PID号

import os
print(os.getppid())

执行结果:
6624

# os.path部分

# 输出路径返回当前系统规范化的绝对路径 - os.path.abspath

os.path.abspath的功能很强大:

  1. 当前的系统是win,输入linux的路径结构,abspath就会默认把路径结构更改成当前系统规范的路径结构
  2. 如果输入的是相对路径,abspath会默认把相对路径更改成绝对路径
import os
print(os.path.abspath("D:\python\PyCharm资源\one\模块\python1\python2\python3/python4"))
print(os.path.abspath("python1\python2\python3/python4"))

执行结果:
D:\python\PyCharm资源\one\模块\python1\python2\python3\python4
D:\python\PyCharm资源\one\模块\python1\python2\python3\python4

**注意:**这里的相对路径更改成绝对路径,其实就是获取当前路径,在拼接输入的路径,所以这里要注意

# 路径分割,分割最后一个文件名或目录名 - os.path.split

路径分割,输入一个路径,会将路径的最后一个文件名目录名分割出来,以元组的方法显示

import os
print(os.path.split("D:\python\PyCharm资源\one\模块\python1"))

执行结果:
('D:\\python\\PyCharm资源\\one\\模块', 'python1')

# 获取os.path.split分割后的第一个值 - os.path.dirname

获取os.path.split分割后的第一个值

格式:os.path.dirname(路径)

import os
print(os.path.dirname("D:\python\PyCharm资源\one\模块\python1"))

执行结果:
D:\python\PyCharm资源\one\模块

# 获取os.path.split分割后的最后一个值 - os.path.basename

获取os.path.split分割后的最后一个值

格式:os.path.basename(路径)

import os
print(os.path.basename("D:\python\PyCharm资源\one\模块\python1"))

执行结果:
python1

# 获取当前文件的上级目录的绝对路径

import os
import sys
start_path = os.path.dirname(os.path.dirname(__file__))
sys.path.append(start_path)

## 为什么要模拟这个实验呢,在正式做项目的时候,对于自定义模块的导入路径就成了个问题,上面这四行代码就是比较完美的解决这问题,
## 获取到项目的主目录
## 在把获取到的主目录路径添加到当前项目的内存模块地址列表中

# 总结

无论是os.path.split、os.path.basename、os.path.dirname都是一个独立的方法,其实split更像是basename跟dirname的集合版,为什么要写到一起,还把basename跟dirname写在split下,博主完全没有看不起basename跟dirname的意思,就是博主自己总结认为,这三个方法就是一体的,无论是split是basename跟dirname的结合版,还是basename跟dirname是split的拆分版,博主都认为竟然会出现这三个方法,那就肯定有应用这三个方法的某个场景

# 多路径组合 - os.path.join

将输入的多个路径组合起来,组合符按当前系统规定的路径分隔符来分隔

import os
print(os.path.join("D:\python\PyCharm资源\one\模块","aaa","bbb","ccc"))
print(os.path.join("D:/python/PyCharm资源/one/模块","aaa","bbb","ccc"))

执行结果:
D:\python\PyCharm资源\one\模块\aaa\bbb\ccc
D:/python/PyCharm资源/one/模块\aaa\bbb\ccc

# 检测输入的路径是否存在的 - os.path.exists

如果检测的路径:

  1. 存在,则返回:True
  2. 不存在,则返回:Fales
import os
print(os.path.exists("D:\python\PyCharm资源\one\模块\os模块.py"))
print(os.path.exists("D:\python\PyCharm资源\one\模块\os模块.py1"))

执行结果:
True
False

# 检测输入的路径是不是绝对路径 -os.path.isabs

如果检测的路径:

  1. 是绝对路径,则返回:True
  2. 不是绝对路径,则返回:Fales
import os
print(os.path.isabs("os模块.py"))
print(os.path.isabs("D:\python\PyCharm资源\one\模块\os模块.py"))

执行结果:
False
True

# 输入的路径是否是一个存在的文件 - os.path.isfile

如果检测的路径:

  1. 是一个存在的文件,则返回:True
  2. 不是一个存在的文件,则返回:Fales
import os
print(os.path.isfile("os模块.py"))
print(os.path.isfile("D:\python\PyCharm资源\one\模块\os模块.py"))
print(os.path.isfile("D:\python\PyCharm资源\one\模块\python1"))
print(os.path.isdir("D:\python\PyCharm资源\one\模块\sss"))

执行结果:
True
True
False
False

# 输入的路径是否是一个存在的目录 - os.path.isdir

如果检测的路径:

  1. 是一个存在的目录,则返回:True
  2. 不是一个存在的目录,则返回:Fales
import os
print(os.path.isdir("python1"))
print(os.path.isdir("D:\python\PyCharm资源\one\模块\python1"))
print(os.path.isdir("D:\python\PyCharm资源\one\模块\os模块.py"))
print(os.path.isdir("D:\python\PyCharm资源\one\模块\sss"))

执行结果:
True
True
False
False

# 返回路径的最后访问时间 - os.path.getatime

返回输入的路径指向的文件或目录的最后访问时间

返回的值是时间戳格式的数据

需要手动的进行时间格式的转换

import os
import time
print(os.path.getatime("a"))
print(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(os.path.getatime("a"))))

执行结果:
1569146582.77345
2019-09-22 18:03:02

# 返回路径的最后修改时间 - os.path.getmtime

返回输入的路径指向的文件或目录的最后修改时间

返回的值是时间戳格式的数据

需要手动的进行时间格式的转换

import os
import time
print(os.path.getmtime("a"))
print(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(os.path.getatime("a"))))

执行结果:
1568080930.8553624
2019-09-22 18:03:02

# 返回路径指向文件的大小 - os.path.getsize

返回输入的路径指向的文件或目录的大小

注意:这里目录的大小永远都是4096,目录的大小不包含目录里面的文件或目录的大小

import os
print(os.path.getsize("D:\python\PyCharm资源\one\模块\os模块.py"))
print(os.path.getsize(r"D:\python\PyCharm资源\one\模块\a"))

执行结果:
1240
4096